﻿using System;
using System.Windows.Forms;
using S7.Net;
using S7PlcDataManager.S7Plc;
using ZbSkin.Frm;
using ZbSkin.Tools;

namespace S7PlcDataManager.Controls
{
    public partial class DataSetControl : UserControl
    {
        private readonly S7PlcHelper _s7PlcHelper;
        private string _variable;
        private VarType _valueType;

        public DataSetControl(S7PlcHelper s7PlcHelper)
        {
            InitializeComponent();
            _s7PlcHelper = s7PlcHelper;
        }

        private void DataSetControl_Load(object sender, EventArgs e)
        {
            SetRegion();
        }

        private void DataSetControl_Resize(object sender, EventArgs e)
        {
            SetRegion();
        }

        private void SetRegion()
        {
            this.SetRegion(30);
        }

        public void ChangeDataType(string variable, VarType valueType)
        {
            _variable = variable;
            _valueType = valueType;
        }

        private void btn_set_Click(object sender, EventArgs e)
        {
            if (!_s7PlcHelper.IsConnected)
            {
                MessageBoxEx.Warning(@"PLC未连接", ParentForm);
                return;
            }

            tb_variable.Text = _variable;
            tb_valtype.Text = _valueType.ToString();

            var valueText = tb_val.Text.Trim();
            if (string.IsNullOrWhiteSpace(valueText))
            {
                MessageBoxEx.Warning(@"请输入变量值", ParentForm);
                return;
            }

            SetPlcData(valueText);
        }

        private void SetPlcData(string valueText)
        {
            switch (_valueType)
            {
                case VarType.String:
                    WritePlcString(valueText);
                    break;
                case VarType.S7String:
                    WritePlcS7String(valueText);
                    break;
                default:
                    WritePlcObject(valueText);
                    break;
            }
        }

        private void WritePlcObject(string valueText)
        {
            var value = GetVariableValue(_valueType, valueText);
            if (value == null)
            {
                MessageBoxEx.Warning($@"不支持的数据类型[{_valueType}]", ParentForm);
                return;
            }

            if (_s7PlcHelper.WriteVariable(_variable, value))
            {
                MessageBoxEx.Info(@"设置数据成功", ParentForm);
            }
            else
            {
                MessageBoxEx.Warning(_s7PlcHelper.LastErrorMsg, ParentForm);
            }
        }

        private void WritePlcString(string valueText)
        {
            if (_s7PlcHelper.WriteString(_variable, valueText))
            {
                MessageBoxEx.Info(@"设置数据成功", ParentForm);
            }
            else
            {
                MessageBoxEx.Warning(_s7PlcHelper.LastErrorMsg, ParentForm);
            }
        }

        private void WritePlcS7String(string valueText)
        {
            if (_s7PlcHelper.WriteS7String(_variable, valueText))
            {
                MessageBoxEx.Info(@"设置数据成功", ParentForm);
            }
            else
            {
                MessageBoxEx.Warning(_s7PlcHelper.LastErrorMsg, ParentForm);
            }
        }

        private static object GetVariableValue(VarType varType, string text)
        {
            switch (varType)
            {
                case VarType.Bit:
                    return bool.Parse(text);
                case VarType.Byte:
                    return byte.Parse(text);
                case VarType.Word:
                    return ushort.Parse(text);
                case VarType.DWord:
                    return uint.Parse(text);
                case VarType.Int:
                    return short.Parse(text);
                case VarType.DInt:
                    return int.Parse(text);
                case VarType.Real:
                    return float.Parse(text);
                case VarType.LReal:
                    return double.Parse(text);
                default:
                    return null;
            }
        }
    }
}
